<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>liubin website</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="description" content="用SVG连接两个div的直线，拖动实时改变位置用d3.js动态添加 path,line 节点，并动态修改节点属性 1.产品经理提出的需求    用带箭头的虚线将两个位置不固定的div连接起来,初听到这个需求一头雾水，传统的div可以做直线，但斜起来不太好做，幸亏之前接触过svg,里面有一个line标签，知道起始中止两个点的位置，就可以将两个点连接起来了。  至于箭头,可以这么做先定义箭头：  12">
    <meta property="og:type" content="article">
    <meta property="og:title" content="liubin website">
    <meta property="og:url" content="http://yoursite.com/2018/03/10/svg2/index.html">
    <meta property="og:site_name" content="liubin website">
    <meta property="og:description" content="用SVG连接两个div的直线，拖动实时改变位置用d3.js动态添加 path,line 节点，并动态修改节点属性 1.产品经理提出的需求    用带箭头的虚线将两个位置不固定的div连接起来,初听到这个需求一头雾水，传统的div可以做直线，但斜起来不太好做，幸亏之前接触过svg,里面有一个line标签，知道起始中止两个点的位置，就可以将两个点连接起来了。  至于箭头,可以这么做先定义箭头：  12">
    <meta property="og:image" content="https://github.com/liubin915249126/javascript/blob/master/SVG/image/svgDrag.gif">
    <meta property="og:updated_time" content="2018-03-10T09:51:25.000Z">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="liubin website">
    <meta name="twitter:description" content="用SVG连接两个div的直线，拖动实时改变位置用d3.js动态添加 path,line 节点，并动态修改节点属性 1.产品经理提出的需求    用带箭头的虚线将两个位置不固定的div连接起来,初听到这个需求一头雾水，传统的div可以做直线，但斜起来不太好做，幸亏之前接触过svg,里面有一个line标签，知道起始中止两个点的位置，就可以将两个点连接起来了。  至于箭头,可以这么做先定义箭头：  12">
    <meta name="twitter:image" content="https://github.com/liubin915249126/javascript/blob/master/SVG/image/svgDrag.gif">
    <link rel="stylesheet" href="./style.css">

</head>

<body>
    <div id="container">
        <div id="wrap">
            <header class="header">
                <a href="../index.html" target="_blank">
                    <img src="../img/liubin.jpg" class="lb_logo">
                    <span>刘宾</span>
                </a>

                <span>
                    <a class="logo_a" href="../index.html" target="_blank">返回首页</a>
                </span>
            </header>
            <div class="outer">
                <section id="main">
                    <article id="post-svg2" class="article article-type-post" itemscope itemprop="blogPost">
                        <div class="article-meta">
                            <a href="/2018/03/10/svg2/" class="article-date">
                                <time datetime="2018-03-10T09:51:17.076Z" itemprop="datePublished">2018-03-10</time>
                            </a>

                        </div>
                        <div class="article-inner">


                            <div class="article-entry" itemprop="articleBody">

                                <h2 id="用SVG连接两个div的直线，拖动实时改变位置">
                                    <a href="#用SVG连接两个div的直线，拖动实时改变位置" class="headerlink" title="用SVG连接两个div的直线，拖动实时改变位置"></a>用SVG连接两个div的直线，拖动实时改变位置</h2>
                                <p>
                                    <img src="https://github.com/liubin915249126/javascript/raw/master/SVG/image/svgDrag.gif" alt="效果图">
                                    <br>用d3.js动态添加 path,line 节点，并动态修改节点属性</p>
                                <h4 id="1-产品经理提出的需求">
                                    <a href="#1-产品经理提出的需求" class="headerlink" title="1.产品经理提出的需求"></a>1.产品经理提出的需求</h4>
                                <blockquote>
                                </blockquote>
                                <p> 用带箭头的虚线将两个位置不固定的div连接起来,初听到这个需求一头雾水，传统的div可以做直线，但斜起来不太好做，幸亏之前接触过svg,里面有一个line标签，知道起始中止两个点的位置，就可以将两个点连接起来了。
                                    <br> 至于箭头,可以这么做先定义箭头：
                                    <br>
                                    <figure class="highlight js">
                                        <table>
                                            <tr>
                                                <td class="gutter">
                                                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                                                </td>
                                                <td class="code">
                                                    <pre><span class="line">&lt;svg&gt;</span><br><span class="line">    &lt;defs&gt;</span><br><span class="line">        &lt;marker id=<span class="string">"arrow"</span> markerUnits=<span class="string">"strokeWidth"</span> markerWidth=<span class="string">"12"</span> markerHeight=<span class="string">"12"</span> viewBox=<span class="string">"0 0 12 12"</span> refX=<span class="string">"6"</span> refY=<span class="string">"6"</span> orient=<span class="string">"auto"</span>&gt;</span><br><span class="line">            &lt;path xmlns=<span class="string">"http://www.w3.org/2000/svg"</span> d=<span class="string">"M2,2 L10,6 L2,10 L6,6 L2,2"</span> style=<span class="string">"fill: #000000;"</span> /&gt;</span><br><span class="line">        &lt;<span class="regexp">/marker&gt;</span></span><br><span class="line"><span class="regexp">    &lt;/</span>defs&gt;</span><br><span class="line">&lt;<span class="regexp">/svg&gt;</span></span><br></pre>
                                                </td>
                                            </tr>
                                        </table>
                                    </figure>
                                </p>
                                <p> 将箭头放在直线上：marker-end=”url(#arrow)”
                                    <br>
                                    <figure class="highlight js">
                                        <table>
                                            <tr>
                                                <td class="gutter">
                                                    <pre><span class="line">1</span><br></pre>
                                                </td>
                                                <td class="code">
                                                    <pre><span class="line">&lt;line  x1=<span class="string">"0"</span> y1=<span class="string">"0"</span> x2=<span class="string">"200"</span> y2=<span class="string">"50"</span> stroke=<span class="string">"#000"</span> stroke-width=<span class="string">"2"</span> marker-end=<span class="string">"url(#arrow)"</span>stroke-dasharray=<span class="string">"10,10"</span>&gt;&lt;/line&gt;</span><br></pre>
                                                </td>
                                            </tr>
                                        </table>
                                    </figure>
                                </p>
                                <blockquote>
                                </blockquote>
                                <h4 id="2-确定起始中止两个点左上角的位置">
                                    <a href="#2-确定起始中止两个点左上角的位置" class="headerlink" title="2.确定起始中止两个点左上角的位置"></a>2.确定起始中止两个点左上角的位置</h4>
                                <blockquote>
                                </blockquote>
                                <p> 需要连接的两个div及SVG都相对于某一个div.wrap绝对定位，可以先求得两个div左上角相对与div.wrap坐标：
                                    <br>
                                    <figure class="highlight js">
                                        <table>
                                            <tr>
                                                <td class="gutter">
                                                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre>
                                                </td>
                                                <td class="code">
                                                    <pre><span class="line"> <span class="comment">//获取元素左上角相对于某一元素的的位置</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">getElCoordinate</span>(<span class="params">dom</span>) </span>&#123;</span><br><span class="line">             <span class="keyword">var</span> t = dom.offsetTop;</span><br><span class="line">             <span class="keyword">var</span> l = dom.offsetLeft;</span><br><span class="line">             <span class="keyword">var</span> w = dom.offsetWidth;</span><br><span class="line">             <span class="keyword">var</span> h = dom.offsetHeight;</span><br><span class="line">             dom = dom.offsetParent;</span><br><span class="line">             <span class="keyword">while</span> (!$(dom).hasClass(<span class="string">'wrap'</span>)) &#123;</span><br><span class="line">                 t += dom.offsetTop;</span><br><span class="line">                 l += dom.offsetLeft;</span><br><span class="line">                 dom = dom.offsetParent;</span><br><span class="line">             &#125;; <span class="keyword">return</span> &#123;</span><br><span class="line">                 top: t,<span class="comment">//Y轴坐标</span></span><br><span class="line">                 left: l,<span class="comment">//X轴坐标</span></span><br><span class="line">                 width:w,<span class="comment">//元素宽度</span></span><br><span class="line">                 height:h<span class="comment">//元素高度 </span></span><br><span class="line">             &#125;;</span><br><span class="line">         &#125;</span><br><span class="line">&#125;)</span><br></pre>
                                                </td>
                                            </tr>
                                        </table>
                                    </figure>
                                </p>
                                <blockquote>
                                </blockquote>
                                <h4 id="3-确定连接点在div上的位置：">
                                    <a href="#3-确定连接点在div上的位置：" class="headerlink" title="3.确定连接点在div上的位置："></a>3.确定连接点在div上的位置：</h4>
                                <blockquote>
                                </blockquote>
                                <p> 分为两种情况：终点div位于起点div上方,终点div位于起点div下方。
                                    <br>
                                    <figure class="highlight js">
                                        <table>
                                            <tr>
                                                <td class="gutter">
                                                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre>
                                                </td>
                                                <td class="code">
                                                    <pre><span class="line"><span class="keyword">var</span> pos1 = getElCoordinate($(<span class="string">'.item1'</span>)[<span class="number">0</span>])<span class="comment">//起点div的位置</span></span><br><span class="line"><span class="keyword">var</span> pos2 = getElCoordinate($(<span class="string">'.item2'</span>)[<span class="number">0</span>])<span class="comment">//终点div的位置</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getPos</span>(<span class="params">pos1, pos2</span>)</span>&#123;</span><br><span class="line">           <span class="comment">//分两种情况</span></span><br><span class="line">           <span class="keyword">var</span> x1,y1,x2,y2;</span><br><span class="line">           <span class="keyword">if</span>(pos2.top&lt;pos1.top)&#123;</span><br><span class="line">               x1 = pos1.left + pos1.width/<span class="number">2</span>;</span><br><span class="line">               y1 = pos1.top;</span><br><span class="line">               y2 = pos2.top + pos2.height</span><br><span class="line">              <span class="keyword">if</span>(pos2.left&lt;pos1.left)&#123;</span><br><span class="line">                 x2 = pos2.left + pos2.width/<span class="number">2</span></span><br><span class="line">           &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">               x1 = pos1.left + pos1.width / <span class="number">2</span>;</span><br><span class="line">               y1 = pos1.top + pos1.height;</span><br><span class="line">               x2 = pos2.left + pos2.width/<span class="number">2</span></span><br><span class="line">               y2 = pos2.top </span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">return</span> &#123;</span><br><span class="line">               start :&#123;<span class="attr">x</span>:x1,<span class="attr">y</span>:y1&#125;,</span><br><span class="line">               end : &#123;<span class="attr">x</span>:x2,<span class="attr">y</span>:y2&#125;</span><br><span class="line">           &#125;</span><br><span class="line">        &#125;</span><br></pre>
                                                </td>
                                            </tr>
                                        </table>
                                    </figure>
                                </p>
                                <blockquote>
                                </blockquote>
                                <h4 id="4-确定起止点位置后连线。">
                                    <a href="#4-确定起止点位置后连线。" class="headerlink" title="4.确定起止点位置后连线。"></a>4.确定起止点位置后连线。</h4>
                                <blockquote>
                                </blockquote>
                                <figure class="highlight js">
                                    <table>
                                        <tr>
                                            <td class="gutter">
                                                <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre>
                                            </td>
                                            <td class="code">
                                                <pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">move</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="keyword">var</span> pos1 = getElCoordinate($(<span class="string">'.item1'</span>)[<span class="number">0</span>])</span><br><span class="line">            <span class="keyword">var</span> pos2 = getElCoordinate($(<span class="string">'.item2'</span>)[<span class="number">0</span>])</span><br><span class="line">            <span class="keyword">var</span> start = getPos(pos1, pos2).start</span><br><span class="line">            <span class="keyword">var</span> end = getPos(pos1, pos2).end</span><br><span class="line"></span><br><span class="line">            $(<span class="string">'#line'</span>).attr(&#123; <span class="attr">x1</span>: start.x, <span class="attr">y1</span>: start.y, <span class="attr">x2</span>: end.x, <span class="attr">y2</span>: end.y &#125;)</span><br><span class="line">            $(<span class="string">'#path'</span>).attr(&#123; <span class="attr">d</span>: <span class="string">'M20,20 L100,100'</span> &#125;)</span><br><span class="line">        &#125;</span><br><span class="line">        move()</span><br></pre>
                                            </td>
                                        </tr>
                                    </table>
                                </figure>
                                <blockquote>
                                </blockquote>
                                <h4 id="5-两个div分别拖动并保持线始终连接">
                                    <a href="#5-两个div分别拖动并保持线始终连接" class="headerlink" title="5.两个div分别拖动并保持线始终连接"></a>5.两个div分别拖动并保持线始终连接</h4>
                                <blockquote>
                                </blockquote>
                                <pre><code class="js">  drag($(<span class="string">'.item'</span>), move)
                      <span class="function"><span class="keyword">function</span> <span class="title">drag</span>(<span class="params">obj,callback</span>) </span>{
                         <span class="keyword">var</span> dragEles = obj;
                         dragEles.each(<span class="function"><span class="keyword">function</span>(<span class="params">index, dragEleDom</span>)</span>{
                             <span class="keyword">var</span> _move = <span class="literal">false</span>;<span class="comment">//移动标记</span>
                             <span class="keyword">var</span> _x, _y;<span class="comment">//鼠标离控件左上角的相对位置</span>
                             <span class="keyword">var</span> dragEle = $(dragEleDom)
                             dragEle.click(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{
                                 <span class="comment">//alert("click");//点击（松开后触发）</span>
                             }).mousedown(<span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{
                                 _move = <span class="literal">true</span>;
                                 _x = e.pageX - <span class="built_in">parseInt</span>(dragEle.css(<span class="string">"left"</span>));
                                 _y = e.pageY - <span class="built_in">parseInt</span>(dragEle.css(<span class="string">"top"</span>));
                                 <span class="comment">// dragEle.fadeTo(20, 0.9);//点击后开始拖动并透明显示</span>
                             });
                             $(<span class="built_in">document</span>).mousemove(<span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{
                                 <span class="keyword">if</span> (_move) {
                                     <span class="keyword">var</span> x = e.pageX - _x;<span class="comment">//移动时根据鼠标位置计算控件左上角的绝对位置</span>
                                     <span class="keyword">var</span> y = e.pageY - _y;
                                     dragEle.css({ <span class="attr">top</span>: y, <span class="attr">left</span>: x });<span class="comment">//控件新位置</span>
                                     <span class="keyword">if</span>(callback){callback()}
                                 }
                             }).mouseup(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{
                                 _move = <span class="literal">false</span>;
                                 dragEle.fadeTo(<span class="string">"fast"</span>, <span class="number">1</span>);<span class="comment">//松开鼠标后停止移动并恢复成不透明</span>
                             });
                         })
                    
                    }
                    </code></pre>
                                <blockquote>
                                </blockquote>
                                <h4 id="梳理下流程：分析需求-gt-确定使用SVG-gt-找到连接点-gt-连线-gt-拖动时保持连线。">
                                    <a href="#梳理下流程：分析需求-gt-确定使用SVG-gt-找到连接点-gt-连线-gt-拖动时保持连线。" class="headerlink" title="梳理下流程：分析需求&gt;确定使用SVG&gt;找到连接点&gt;连线&gt;拖动时保持连线。"></a>梳理下流程：分析需求&gt;确定使用SVG&gt;找到连接点&gt;连线&gt;拖动时保持连线。</h4>
                                <h4 id="源码托管于github欢迎star">
                                    <a href="#源码托管于github欢迎star" class="headerlink" title="源码托管于github欢迎star"></a>源码托管于
                                    <a href="https://github.com/liubin915249126/javascript/tree/master/SVG" target="_blank" rel="noopener">github</a>欢迎star</h4>
                                    <h4><a href="../example/svg1.html" target="_blank" rel="noopener">实例应用</a></h4>

                            </div>
                            <footer class="article-footer">
                                <a data-url="http://yoursite.com/2018/03/10/svg2/" data-id="cjep1icbc0005upx89rqz9rtz" class="article-share-link">Teilen</a>


                            </footer>
                        </div>


                        <nav id="article-nav">

                            <a href="/2018/03/12/lencharts/" id="article-nav-newer" class="article-nav-link-wrap">
                                <strong class="article-nav-caption">Neuer</strong>
                                <div class="article-nav-title">

                                    (no title)

                                </div>
                            </a>


                            <a href="/2018/03/10/svg1/" id="article-nav-older" class="article-nav-link-wrap">
                                <strong class="article-nav-caption">Älter</strong>
                                <div class="article-nav-title"></div>
                            </a>

                        </nav>


                    </article>
                </section>
            </div>
            <!-- Global site tag (gtag.js) - Google Analytics -->
            <script async src="https://www.googletagmanager.com/gtag/js?id=UA-115451143-1"></script>
            <script>
                window.dataLayer = window.dataLayer || [];

                function gtag() {
                    dataLayer.push(arguments);
                }
                gtag('js', new Date());

                gtag('config', 'UA-115451143-1');
            </script>
</body>

</html>